/**
 *****************************************************************************
 * @file     _reg_spiflash.h
 *
 * @brief    -
 *
 * Copyright (C) RealMega 2019-2020
 *
 *****************************************************************************
 */

#ifndef __REG_SPIFLASH_H__
#define __REG_SPIFLASH_H__

#include "type_def.h"



//MACROS of register r_rev_id
#define SPIFLASH_R_REV_ID_REV_ID_MASK                                         (0xFFUL)
#define SPIFLASH_R_REV_ID_REV_ID(N)                                           (((N)<<0)&0xFFUL)


//MACROS of register tx_cmd_addr
#define SPIFLASH_TX_CMD_ADDR_TX_ADDR_MASK                                     (0xFFFFFF00UL)
#define SPIFLASH_TX_CMD_ADDR_TX_ADDR(N)                                       (((N)<<8)&0xFFFFFF00UL)
#define SPIFLASH_TX_CMD_ADDR_TX_CMD_MASK                                      (0xFFUL)
#define SPIFLASH_TX_CMD_ADDR_TX_CMD(N)                                        (((N)<<0)&0xFFUL)


//MACROS of register trans_mode
#define SPIFLASH_TRANS_MODE_TX_CONT_MODE                                      (1<<24)
#define SPIFLASH_TRANS_MODE_TX_BLOCK_SIZE_MASK                                (0x1FF00UL)
#define SPIFLASH_TRANS_MODE_TX_BLOCK_SIZE(N)                                  (((N)<<8)&0x1FF00UL)
#define SPIFLASH_TRANS_MODE_TX_MODE_MASK                                      (0xFFUL)
#define SPIFLASH_TRANS_MODE_TX_MODE(N)                                        (((N)<<0)&0xFFUL)


//MACROS of register tx_fifo_data
#define SPIFLASH_TX_FIFO_DATA_TX_DATA_MASK                                    (0xFFUL)
#define SPIFLASH_TX_FIFO_DATA_TX_DATA(N)                                      (((N)<<0)&0xFFUL)


//MACROS of register status
#define SPIFLASH_STATUS_READ_STATE_BUSY                                       (1<<9)
#define SPIFLASH_STATUS_RX_FIFO_CNT_MASK                                      (0x1F0UL)
#define SPIFLASH_STATUS_RX_FIFO_CNT(N)                                        (((N)<<4)&0x1F0UL)
#define SPIFLASH_STATUS_RX_FIFO_EMPTY                                         (1<<3)
#define SPIFLASH_STATUS_TX_FIFO_FULL                                          (1<<2)
#define SPIFLASH_STATUS_TX_FIFO_EMPTY                                         (1<<1)
#define SPIFLASH_STATUS_BUSY_STAT                                             (1<<0)


//MACROS of register rx_fifo_data
#define SPIFLASH_RX_FIFO_DATA_RX_DATA_MASK                                    (0xFFFFFFFFUL)
#define SPIFLASH_RX_FIFO_DATA_RX_DATA(N)                                      (((N)<<0)&0xFFFFFFFFUL)


//MACROS of register flash_config
#define SPIFLASH_FLASH_CONFIG_CMD_QUAD                                        (1<<16)
#define SPIFLASH_FLASH_CONFIG_CLK_DIVIDER_MASK                                (0xFF00UL)
#define SPIFLASH_FLASH_CONFIG_CLK_DIVIDER(N)                                  (((N)<<8)&0xFF00UL)
#define SPIFLASH_FLASH_CONFIG_DIN_CAP_EDGE                                    (1<<7)
#define SPIFLASH_FLASH_CONFIG_SAMPLE_DELAY_MASK                               (0x70UL)
#define SPIFLASH_FLASH_CONFIG_SAMPLE_DELAY(N)                                 (((N)<<4)&0x70UL)
#define SPIFLASH_FLASH_CONFIG_DUAL_MODE                                       (1<<3)
#define SPIFLASH_FLASH_CONFIG_HOLD_PIN                                        (1<<2)
#define SPIFLASH_FLASH_CONFIG_WPROTECT_PIN                                    (1<<1)
#define SPIFLASH_FLASH_CONFIG_QUAD_MODE                                       (1<<0)


//MACROS of register fifo_ctrl
#define SPIFLASH_FIFO_CTRL_TX_FIFO_CLR                                        (1<<1)
#define SPIFLASH_FIFO_CTRL_RX_FIFO_CLR                                        (1<<0)


//MACROS of register dual_spi
#define SPIFLASH_DUAL_SPI_CS_REG                                              (1<<9)
#define SPIFLASH_DUAL_SPI_CS_FORCE                                            (1<<8)
#define SPIFLASH_DUAL_SPI_DIFF_128M_DIFF_CMD_EN                               (1<<7)
#define SPIFLASH_DUAL_SPI_SPI_CS1_SEL1                                        (1<<6)
#define SPIFLASH_DUAL_SPI_SPI_CS1_SEL                                         (1<<5)
#define SPIFLASH_DUAL_SPI_AHB_READ_DISABLE                                    (1<<4)
#define SPIFLASH_DUAL_SPI_SPI_128M                                            (1<<3)
#define SPIFLASH_DUAL_SPI_SPI_SIZE_MASK                                       (0x6UL)
#define SPIFLASH_DUAL_SPI_SPI_SIZE(N)                                         (((N)<<1)&0x6UL)
#define SPIFLASH_DUAL_SPI_SPI_CS_NUM                                          (1<<0)


//MACROS of register r_read_cmd
#define SPIFLASH_R_READ_CMD_DREAD_CMD_MASK                                    (0xFF000000UL)
#define SPIFLASH_R_READ_CMD_DREAD_CMD(N)                                      (((N)<<24)&0xFF000000UL)
#define SPIFLASH_R_READ_CMD_READ_CMD_MASK                                     (0xFF0000UL)
#define SPIFLASH_R_READ_CMD_READ_CMD(N)                                       (((N)<<16)&0xFF0000UL)
#define SPIFLASH_R_READ_CMD_FREAD_CMD_MASK                                    (0xFF00UL)
#define SPIFLASH_R_READ_CMD_FREAD_CMD(N)                                      (((N)<<8)&0xFF00UL)
#define SPIFLASH_R_READ_CMD_QREAD_CMD_MASK                                    (0xFFUL)
#define SPIFLASH_R_READ_CMD_QREAD_CMD(N)                                      (((N)<<0)&0xFFUL)


//MACROS of register nand_cfg1
#define SPIFLASH_NAND_CFG1_RAM_READ_CMD_MASK                                  (0xFF000000UL)
#define SPIFLASH_NAND_CFG1_RAM_READ_CMD(N)                                    (((N)<<24)&0xFF000000UL)
#define SPIFLASH_NAND_CFG1_GET_STS_CMD_MASK                                   (0xFF0000UL)
#define SPIFLASH_NAND_CFG1_GET_STS_CMD(N)                                     (((N)<<16)&0xFF0000UL)
#define SPIFLASH_NAND_CFG1_PAGE_READ_CMD_MASK                                 (0xFF00UL)
#define SPIFLASH_NAND_CFG1_PAGE_READ_CMD(N)                                   (((N)<<8)&0xFF00UL)
#define SPIFLASH_NAND_CFG1_NAND_ADDR_26_25_MASK                               (0x6UL)
#define SPIFLASH_NAND_CFG1_NAND_ADDR_26_25(N)                                 (((N)<<1)&0x6UL)
#define SPIFLASH_NAND_CFG1_NAND_SEL                                           (1<<0)


//MACROS of register nand_cfg2
#define SPIFLASH_NAND_CFG2_STST_QIP_MASK                                      (0xFF0000UL)
#define SPIFLASH_NAND_CFG2_STST_QIP(N)                                        (((N)<<16)&0xFF0000UL)
#define SPIFLASH_NAND_CFG2_PROGRAM_EXE_CMD_MASK                               (0xFF00UL)
#define SPIFLASH_NAND_CFG2_PROGRAM_EXE_CMD(N)                                 (((N)<<8)&0xFF00UL)
#define SPIFLASH_NAND_CFG2_GET_STS_ADDR_MASK                                  (0xFFUL)
#define SPIFLASH_NAND_CFG2_GET_STS_ADDR(N)                                    (((N)<<0)&0xFFUL)


//MACROS of register dummy_cycle_cfg
#define SPIFLASH_DUMMY_CYCLE_CFG_DUMMY_CYCLE_MASK                             (0xF00UL)
#define SPIFLASH_DUMMY_CYCLE_CFG_DUMMY_CYCLE(N)                               (((N)<<8)&0xF00UL)
#define SPIFLASH_DUMMY_CYCLE_CFG_TPD_SEL_MASK                                 (0xCUL)
#define SPIFLASH_DUMMY_CYCLE_CFG_TPD_SEL(N)                                   (((N)<<2)&0xCUL)
#define SPIFLASH_DUMMY_CYCLE_CFG_DUMMY_CYCLE_EN                               (1<<1)
#define SPIFLASH_DUMMY_CYCLE_CFG_FOUR_BYTE_ADDR                               (1<<0)


//MACROS of register diff_128m_cmd
#define SPIFLASH_DIFF_128M_CMD_FOURTH_128M_CMD_MASK                           (0xFF000000UL)
#define SPIFLASH_DIFF_128M_CMD_FOURTH_128M_CMD(N)                             (((N)<<24)&0xFF000000UL)
#define SPIFLASH_DIFF_128M_CMD_THIRD_128M_CMD_MASK                            (0xFF0000UL)
#define SPIFLASH_DIFF_128M_CMD_THIRD_128M_CMD(N)                              (((N)<<16)&0xFF0000UL)
#define SPIFLASH_DIFF_128M_CMD_SECOND_128M_CMD_MASK                           (0xFF00UL)
#define SPIFLASH_DIFF_128M_CMD_SECOND_128M_CMD(N)                             (((N)<<8)&0xFF00UL)
#define SPIFLASH_DIFF_128M_CMD_FIRST_128M_CMD_MASK                            (0xFFUL)
#define SPIFLASH_DIFF_128M_CMD_FIRST_128M_CMD(N)                              (((N)<<0)&0xFFUL)


//MACROS of register chip_0_start_address
#define SPIFLASH_CHIP_0_START_ADDRESS_CHIP_0_START_ADDR_MASK                  (0xFFFFFFFFUL)
#define SPIFLASH_CHIP_0_START_ADDRESS_CHIP_0_START_ADDR(N)                    (((N)<<0)&0xFFFFFFFFUL)


//MACROS of register chip_0_end_address
#define SPIFLASH_CHIP_0_END_ADDRESS_CHIP_0_END_ADDR_MASK                      (0xFFFFFFFFUL)
#define SPIFLASH_CHIP_0_END_ADDRESS_CHIP_0_END_ADDR(N)                        (((N)<<0)&0xFFFFFFFFUL)


//MACROS of register chip_1_start_address
#define SPIFLASH_CHIP_1_START_ADDRESS_CHIP_1_START_ADDR_MASK                  (0xFFFFFFFFUL)
#define SPIFLASH_CHIP_1_START_ADDRESS_CHIP_1_START_ADDR(N)                    (((N)<<0)&0xFFFFFFFFUL)


//MACROS of register chip_1_end_address
#define SPIFLASH_CHIP_1_END_ADDRESS_CHIP_1_END_ADDR_MASK                      (0xFFFFFFFFUL)
#define SPIFLASH_CHIP_1_END_ADDRESS_CHIP_1_END_ADDR(N)                        (((N)<<0)&0xFFFFFFFFUL)



//r_rev_id, offset:0x0
typedef union
{
    u32 v;
    struct
    {
        u32  rev_id                                  :8; /*[7:0], RO, 8'h11, Revision ID*/
        u32  reserved0                               :24; /*[31:8], RO, 24'h0, reserved*/
    }b;
}t_spiflash_r_rev_id;


//tx_cmd_addr, offset:0x4
typedef union
{
    u32 v;
    struct
    {
        u32  tx_cmd                                  :8; /*[7:0], RWE, 8'h0, Command to be sent to the NOR Flash*/
        u32  tx_addr                                 :24; /*[31:8], RWE, 24'h0, Address to be sent to the NOR Flash,indicating the location of read/write and erase*/
    }b;
}t_spiflash_tx_cmd_addr;


//trans_mode, offset:0x8
typedef union
{
    u32 v;
    struct
    {
        u32  tx_mode                                 :8; /*[7:0], RW, 8'h0, transmit mode bits*/
        u32  tx_block_size                           :9; /*[16:8], RW, 9'h1, byte number of data read*/
        u32  reserved1                               :7; /*[23:17], RO, 7'h0, RESERVED*/
        u32  tx_cont_mode                            :1; /*[24], RW, 1'h0, Tansmit continuse mode enable*/
        u32  reserved0                               :7; /*[31:25], RO, 7'h0, RESERVED*/
    }b;
}t_spiflash_trans_mode;


//tx_fifo_data, offset:0xc
typedef union
{
    u32 v;
    struct
    {
        u32  tx_data                                 :8; /*[7:0], WOE, 8'h0, Transmit FIFO data*/
        u32  reserved0                               :24; /*[31:8], RO, 24'h0, RESERVED*/
    }b;
}t_spiflash_tx_fifo_data;


//status, offset:0x10
typedef union
{
    u32 v;
    struct
    {
        u32  busy_stat                               :1; /*[0], RO, 1'h0, 0:: flash_fsm_idle
                                                          1:: flash_fsm_busy*/
        u32  tx_fifo_empty                           :1; /*[1], RO, 1'h1, 0:: tx_fifo_not_empty
                                                          1:: tx_fifo_empty*/
        u32  tx_fifo_full                            :1; /*[2], RO, 1'h0, 0:: tx_fifo_not_full
                                                          1:: tx_fifo_full*/
        u32  rx_fifo_empty                           :1; /*[3], RO, 1'h1, 0:: rx_fifo_not_empty
                                                          1:: rx_fifo_empty*/
        u32  rx_fifo_cnt                             :5; /*[8:4], RO, 5'h0, Receive FIFO count*/
        u32  read_state_busy                         :1; /*[9], RO, 1'h0, 0:: ahb_fsm_idle
                                                          1:: ahb_fsm_busy*/
        u32  reserved0                               :22; /*[31:10], RO, 22'h0, RESERVED*/
    }b;
}t_spiflash_status;


//rx_fifo_data, offset:0x14
typedef union
{
    u32 v;
    struct
    {
        u32  rx_data                                 :32; /*[31:0], ROE, 32'h0, Receive FIFO data*/
    }b;
}t_spiflash_rx_fifo_data;


//flash_config, offset:0x18
typedef union
{
    u32 v;
    struct
    {
        u32  quad_mode                               :1; /*[0], RWE, 1'h0, Quad mode
                                                          0:: not quad_mode
                                                          1:: quad_mode*/
        u32  wprotect_pin                            :1; /*[1], RWE, 1'h0, Set wproctect pin active
                                                          0:: wpro_pin_as_data_pin
                                                          1:: wpro_pin_active*/
        u32  hold_pin                                :1; /*[2], RWE, 1'h0, Set hold pin active
                                                          0:: hold_pin_as_data_pin
                                                          1:: hold_pin_active*/
        u32  dual_mode                               :1; /*[3], RWE, 1'h0, Dual mode
                                                          0:: not_dual_mode
                                                          1:: dual_mode*/
        u32  sample_delay                            :3; /*[6:4], RWE, 3'h1, spi data input Sample delay; could cowork with din_cap_edge
                                                          0:: 0_internal_sclk_delay
                                                          1:: 1_internal_sclk_delay
                                                          2:: 2_internal_sclk_delay
                                                          3:: 3_internal_sclk_delay*/
        u32  din_cap_edge                            :1; /*[7], RWE, 1'h0, spi data input capture edge
                                                          0:: posedge_of_internal_sclk
                                                          1:: negedge_of_internal_sclk*/
        u32  clk_divider                             :8; /*[15:8], RWE, 8'h1, Clock divider
                                                          0: divide_by_1
                                                          1:: divide_by_1
                                                          2:: divide_by_2
                                                          3:: divide_by_3
                                                          4:: divide_by_4
                                                          5:: divide_by_5
                                                          6:: divide_by_6
                                                          7:: divide_by_7
                                                          8:: divide_by_8*/
        u32  cmd_quad                                :1; /*[16], RWE, 1'h0, Quad Command Enable
                                                          Hardware will regard current command as quad commond if this bit is active*/
        u32  reserved0                               :15; /*[31:17], RO, 15'h0, RESERVED*/
    }b;
}t_spiflash_flash_config;


//fifo_ctrl, offset:0x1c
typedef union
{
    u32 v;
    struct
    {
        u32  rx_fifo_clr                             :1; /*[0], W1C, 1'h0, write 1 to clear rx fifo*/
        u32  tx_fifo_clr                             :1; /*[1], W1C, 1'h0, write 1 to clear tx fifo*/
        u32  reserved0                               :30; /*[31:2], RO, 30'h0, RESERVED*/
    }b;
}t_spiflash_fifo_ctrl;


//dual_spi, offset:0x20
typedef union
{
    u32 v;
    struct
    {
        u32  spi_cs_num                              :1; /*[0], RW, 1'h0, spi cs number
                                                          1'h0:: one_cs
                                                          1'b1:: two_cs*/
        u32  spi_size                                :2; /*[2:1], RW, 2'h0, spi flash size 
                                                          2'h00:: 32M_bits_flash
                                                          2'h01:: 64M_bits_flash
                                                          2'b10:: 16M_bits_flash
                                                          2'b11:: 8M_bits_flash*/
        u32  spi_128m                                :1; /*[3], RW, 1'h0, 128M bits flash*/
        u32  ahb_read_disable                        :1; /*[4], RW, 1'h0, */
        u32  spi_cs1_sel                             :1; /*[5], RW, 1'h0, */
        u32  spi_cs1_sel1                            :1; /*[6], RW, 1'h0, */
        u32  diff_128m_diff_cmd_en                   :1; /*[7], RW, 1'h0, */
        u32  cs_force                                :1; /*[8], RW, 1'h0, */
        u32  cs_reg                                  :1; /*[9], RW, 1'h0, 0:chip 0;
                                                          1:chip 1*/
        u32  reserved0                               :22; /*[31:10], RO, 22'h0, RESERVED*/
    }b;
}t_spiflash_dual_spi;


//r_read_cmd, offset:0x24
typedef union
{
    u32 v;
    struct
    {
        u32  qread_cmd                               :8; /*[7:0], RW, 8'heb, quad read command*/
        u32  fread_cmd                               :8; /*[15:8], RW, 8'h0b, Fast read command*/
        u32  read_cmd                                :8; /*[23:16], RW, 8'h03, Read command*/
        u32  dread_cmd                               :8; /*[31:24], RW, 8'h3b, Dual read command*/
    }b;
}t_spiflash_r_read_cmd;


//nand_cfg1, offset:0x28
typedef union
{
    u32 v;
    struct
    {
        u32  nand_sel                                :1; /*[0], RW, 1'h0, Internal nand flash selection.
                                                          Nand flash also can be selected from pin
                                                          1'h0:: norflash
                                                          1'b1:: nandflash*/
        u32  nand_addr_26_25                         :2; /*[2:1], RW, 2'h0, RESERVED*/
        u32  reserved0                               :5; /*[7:3], RO, 5'h0, RESERVED*/
        u32  page_read_cmd                           :8; /*[15:8], RW, 8'h13, Page read command*/
        u32  get_sts_cmd                             :8; /*[23:16], RW, 8'h0f, Get status command*/
        u32  ram_read_cmd                            :8; /*[31:24], RW, 8'h03, RAM read command*/
    }b;
}t_spiflash_nand_cfg1;


//nand_cfg2, offset:0x2c
typedef union
{
    u32 v;
    struct
    {
        u32  get_sts_addr                            :8; /*[7:0], RW, 8'hc0, Get status address*/
        u32  program_exe_cmd                         :8; /*[15:8], RW, 8'h10, Program execute command*/
        u32  stst_qip                                :8; /*[23:16], RW, 8'h01, */
        u32  reserved0                               :8; /*[31:24], RO, 8'h0, RESERVED*/
    }b;
}t_spiflash_nand_cfg2;


//dummy_cycle_cfg, offset:0x30
typedef union
{
    u32 v;
    struct
    {
        u32  four_byte_addr                          :1; /*[0], RW, 1'h0, Four bytes addess
                                                          1'h0:: 3_bytes_address
                                                          1'b1:: 4_bytes_address*/
        u32  dummy_cycle_en                          :1; /*[1], RW, 1'h0, Dummy cycle enable*/
        u32  tpd_sel                                 :2; /*[3:2], RW, 2'h0, tport selector*/
        u32  reserved1                               :4; /*[7:4], RO, 4'h0, RESERVED*/
        u32  dummy_cycle                             :4; /*[11:8], RW, 4'h8, Dummy cycle count*/
        u32  reserved0                               :20; /*[31:12], RO, 20'h0, RESERVED*/
    }b;
}t_spiflash_dummy_cycle_cfg;


//diff_128m_cmd, offset:0x34
typedef union
{
    u32 v;
    struct
    {
        u32  first_128m_cmd                          :8; /*[7:0], RW, 8'h8c, 1st 128M flash command*/
        u32  second_128m_cmd                         :8; /*[15:8], RW, 8'h8d, 2nd 128M flash command*/
        u32  third_128m_cmd                          :8; /*[23:16], RW, 8'h0, 3rd 128M flash command*/
        u32  fourth_128m_cmd                         :8; /*[31:24], RW, 8'h0, 4th 128M flash command*/
    }b;
}t_spiflash_diff_128m_cmd;


//chip_0_start_address, offset:0x38
typedef union
{
    u32 v;
    struct
    {
        u32  chip_0_start_addr                       :32; /*[31:0], RW, 32'h24000000, chip 0 start address*/
    }b;
}t_spiflash_chip_0_start_address;


//chip_0_end_address, offset:0x3c
typedef union
{
    u32 v;
    struct
    {
        u32  chip_0_end_addr                         :32; /*[31:0], RW, 32'h26000000, chip 0 end address*/
    }b;
}t_spiflash_chip_0_end_address;


//chip_1_start_address, offset:0x40
typedef union
{
    u32 v;
    struct
    {
        u32  chip_1_start_addr                       :32; /*[31:0], RW, 32'h26000000, chip 1 start address*/
    }b;
}t_spiflash_chip_1_start_address;


//chip_1_end_address, offset:0x44
typedef union
{
    u32 v;
    struct
    {
        u32  chip_1_end_addr                         :32; /*[31:0], RW, 32'h28000000, chip 1 end address*/
    }b;
}t_spiflash_chip_1_end_address;

typedef struct
{
    volatile    t_spiflash_r_rev_id                     r_rev_id;
    volatile    t_spiflash_tx_cmd_addr                  tx_cmd_addr;
    volatile    t_spiflash_trans_mode                   trans_mode;
    volatile    t_spiflash_tx_fifo_data                 tx_fifo_data;
    volatile    t_spiflash_status                       status;
    volatile    t_spiflash_rx_fifo_data                 rx_fifo_data;
    volatile    t_spiflash_flash_config                 flash_config;
    volatile    t_spiflash_fifo_ctrl                    fifo_ctrl;
    volatile    t_spiflash_dual_spi                     dual_spi;
    volatile    t_spiflash_r_read_cmd                   r_read_cmd;
    volatile    t_spiflash_nand_cfg1                    nand_cfg1;
    volatile    t_spiflash_nand_cfg2                    nand_cfg2;
    volatile    t_spiflash_dummy_cycle_cfg              dummy_cycle_cfg;
    volatile    t_spiflash_diff_128m_cmd                diff_128m_cmd;
    volatile    t_spiflash_chip_0_start_address         chip_0_start_address;
    volatile    t_spiflash_chip_0_end_address           chip_0_end_address;
    volatile    t_spiflash_chip_1_start_address         chip_1_start_address;
    volatile    t_spiflash_chip_1_end_address           chip_1_end_address;
}t_hwp_spiflash;


#define hwp_spiflash 		    ((t_hwp_spiflash*)0x40300000)

#endif
